import pymysql
from pymysql.cursors import DictCursor
from config.config import *
import logging
from apiException.custom_exception import *  # 导入自定义异常（DatabaseException、GetDataException）
from utils.config_parser import GetConfig


class Database:
    def __init__(self):
        """
        初始化数据库连接：
        - 调用私有方法 _getConnect() 创建连接，赋值给私有属性 self._db（仅类内部访问）
        """
        # 因为只在内部会去访问这个 self._db，因此可以把它设置为私有属性
        self._db = self._getConnect()


    @staticmethod
    def _getConnect():
        __data = GetConfig().get_database_data()
        """
        静态方法：创建数据库连接对象
        - 尝试用配置项连接数据库，失败则抛出自定义异常 DatabaseException
        """
        try:
            # 使用 pymysql 连接数据库，参数从 config 导入
            conn = pymysql.Connect(
                **__data,
                autocommit=True
            )
            return conn
        except Exception as e:
            # 连接失败时记录日志，并抛出自定义异常
            logging.error(f"数据库连接失败, 错误异常是: {e}")
            raise DatabaseException()

    def get_one(self, sql):
        """
        执行 SQL 查询，返回一条结果（字典格式）
        - 失败则抛出自定义异常 GetDataException
        :param sql: 要执行的 SQL 语句
        :return: 查询结果（字典）或抛出异常
        """
        try:
            # 检查数据库连接是否存在
            if self._db:
                # 使用 DictCursor，查询结果以字典形式返回
                with self._db.cursor(DictCursor) as cur:
                    cur.execute(sql)
                    # 获取一条结果
                    return cur.fetchone()
        except Exception as e:
            # 查询失败时记录日志，并抛出自定义异常
            logging.error(f"数据库查询失败, 错误异常是: {e}")
            raise GetDataException()

    def execute_sql(self, *sqs):
        """
        执行 SQL 语句（支持批量执行，如修改、删除）
        - 无需返回结果，失败则抛出自定义异常 ExecuteSqlException
        :param sqs: 不定长参数，接收多个 SQL 语句（打包成元组）
        """
        try:
            # 检查数据库连接是否存在
            if self._db:
                # 使用 DictCursor（虽无返回结果，仍保持游标上下文管理）
                with self._db.cursor(DictCursor) as cur:
                    # 遍历执行所有传入的 SQL 语句
                    for sql in sqs:
                        cur.execute(sql)
        except Exception as e:
            # 执行失败时记录日志，并抛出自定义异常
            logging.error(f"数据库修改、删除失败, 错误异常是: {e}")
            raise ExecuteSqlException()

if __name__ == '__main__':
    # 初始化 Database 类
    db = Database()
    # 定义一条更新语句（修改数据）
    SQL1 = "UPDATE base_data_product_brand SET NAME = '大米' where code = '001'"
    # SQL2 = "select * from tbl_shop"  # 示例查询语句（可取消注释测试）

    # 执行更新操作
    db.execute_sql(SQL1)
    # 执行查询（验证修改结果）
    result = db.get_one("select `code` from base_data_product_brand")
    print(result)